package com.googlecode.cpbi.util;

import java.io.IOException;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.objectweb.asm.ClassReader;
import org.springframework.core.io.Resource;

/**
 * @author Jeremy Wales
 */
public class PackageUtils {
	private static final Log LOG = LogFactory.getLog(PackageUtils.class);
	private static final char PACKAGE_SEPERATOR = '.';
	private static final char PATH_SEPERATOR = '/';
	private static final String ARRAY_CLASS_PREFIX = "[L";

	private PackageUtils() {
	}

	public static String getPackageNameOf(String rootRelativeFileName) {
		String trimmedFileName =
				rootRelativeFileName.startsWith(ARRAY_CLASS_PREFIX)
						? rootRelativeFileName.substring(ARRAY_CLASS_PREFIX.length()) : rootRelativeFileName;
		int endIndex = trimmedFileName.lastIndexOf(PATH_SEPERATOR);
		endIndex = endIndex == -1 ? 0 : endIndex;
		return trimmedFileName.substring(0, endIndex).replace(PATH_SEPERATOR, PACKAGE_SEPERATOR);
	}

	public static boolean matches(String packageName, String[] packageNamePatterns) {
		for (int i = 0; i < packageNamePatterns.length; i++) {
			String pattern = packageNamePatterns[i];
			if (packageName.equals(pattern)) return true;
			int indexOfDeepAnyMatch = pattern.indexOf('*');
			if (indexOfDeepAnyMatch > -1 && packageName.startsWith(pattern.substring(0, indexOfDeepAnyMatch)))
				return true;

		}
		return false;
	}

	public static Set getPackageDependenciesOf(Resource classResource, String[] excludedPackagePatterns) {
		PackageCollectingDependencyVisitor visitor = new PackageCollectingDependencyVisitor(excludedPackagePatterns);
		try {
			ClassReader classReader = new ClassReader(classResource.getInputStream());
			classReader.accept(visitor, false);
		} catch (IOException e) {
			LOG.error("Could not access '" + classResource.getDescription() + "'.", e);
		}
		return visitor.getPackageDependencies();
	}
}
